#include "task_executor.h"
#include <algorithm>
#include <cstddef>
#include <exception>
#include <sstream>
#include <iomanip>
#include <iterator>
#include <unordered_set>
#include <QMetaObject>
#include <QtCore/Qt>
#include <QString>

#include "application/dispatcher/dispatcher_service.h"
#include "application/map/map_application_service.h"
#include "application/map/area/area.h"
#include "application/map/charge/charge_point.h"
#include "application/map/park/park_point.h"
#include "application/map/lift/base_lift.h"
#include "subtasks/move_task.h"
#include "subtasks/lift_task.h"
#include "subtasks/charge_task.h"

namespace application {
namespace task {

std::atomic<uint64_t> TaskExecutor::s_chainCounter{0};

TaskExecutor::TaskExecutor(
    std::shared_ptr<kernel::ILogger> logger,
    std::shared_ptr<vehicle::VehicleService> vehicleService,
    std::shared_ptr<dispatcher::DispatcherService> dispatcherService,
    std::shared_ptr<MapApplicationService> mapService,
    QObject* parent)
    : QObject(parent)
    , m_logger(logger)
    , m_vehicleService(vehicleService)
    , m_dispatcherService(dispatcherService)
    , m_mapService(mapService)
{
    // 连接定时器
    connect(&m_executionTimer, &QTimer::timeout,
            this, &TaskExecutor::executeStep);

    if (m_logger) {
        m_logger->info("TaskExecutor initialized");
    }

    if (m_dispatcherService) {
        m_dispatcherService->setDispatchCallback(
            [this](int agvNumber, const QList<QString>& segment) {
                QMetaObject::invokeMethod(
                    this,
                    [this, agvNumber, segment]() {
                        handleDispatchEvent(agvNumber, segment);
                    },
                    Qt::QueuedConnection);
            });
    }
}

TaskExecutor::~TaskExecutor()
{
    if (m_dispatcherService) {
        m_dispatcherService->setDispatchCallback({});
    }
}

std::string TaskExecutor::addTaskChain(
    int agvNumber,
    std::vector<std::unique_ptr<SubTaskBase>> tasks,
    const std::string& taskName)
{
    if (tasks.empty()) {
        if (m_logger) {
            m_logger->warning("Attempted to add empty task chain");
        }
        return "";
    }

    // 防止同一车辆重复挂载并行任务链
    if (agvNumber >= 0) {
        auto existing = std::find_if(
            m_activeChains.begin(),
            m_activeChains.end(),
            [agvNumber](const TaskChainState& chain) {
                return !chain.finished && chain.agvNumber == agvNumber;
            });
        if (existing != m_activeChains.end()) {
            if (m_logger) {
                m_logger->warning(QString("AGV %1 already has an active task chain (%2), reject new chain")
                    .arg(agvNumber)
                    .arg(QString::fromStdString(existing->chainId)));
            }
            return "";
        }
    }

    TaskChainState chain;
    chain.chainId = generateChainId();
    chain.agvNumber = agvNumber;
    chain.taskName = taskName;
    chain.tasks = std::move(tasks);
    chain.currentTaskIndex = 0;
    chain.paused = false;
    chain.finished = false;
    chain.createTime = std::chrono::system_clock::now();

    // 初始化上下文
    chain.context.chainId = chain.chainId;
    chain.context.taskId = taskName.empty() ? chain.chainId : taskName;
    chain.context.clearError();

    // 设置AGV为被调度器控制（参考 taskchain.cpp:83）
    if (m_vehicleService) {
        auto* agv = m_vehicleService->getVehicle(agvNumber);
        if (agv) {
            agv->setControlledByDispatcher(true);
            // 设置上下文中的AGV指针
            chain.context.agv = agv;
        }
    }

    const std::string chainId = chain.chainId;
    const QString qChainId = QString::fromStdString(chainId);
    const QString qTaskName = QString::fromStdString(taskName);
    const int taskCount = static_cast<int>(chain.tasks.size());

    m_activeChains.push_back(std::move(chain));

    if (m_logger) {
        m_logger->info(QString("Task chain %1 added for AGV %2 with %3 tasks")
            .arg(qChainId)
            .arg(agvNumber)
            .arg(taskCount));
    }

    // 发射任务链添加信号,让ViewModel可以即时获取并显示
    emit taskChainAdded(qChainId, agvNumber, qTaskName);

    return chainId;
}

bool TaskExecutor::pauseTaskChain(const std::string& chainId)
{
    auto* chain = findTaskChain(chainId);
    if (!chain) {
        return false;
    }

    chain->paused = true;

    if (m_logger) {
        m_logger->info(QString("Task chain %1 paused")
            .arg(QString::fromStdString(chainId)));
    }

    return true;
}

bool TaskExecutor::resumeTaskChain(const std::string& chainId)
{
    auto* chain = findTaskChain(chainId);
    if (!chain) {
        return false;
    }

    chain->paused = false;

    if (m_logger) {
        m_logger->info(QString("Task chain %1 resumed")
            .arg(QString::fromStdString(chainId)));
    }

    return true;
}

bool TaskExecutor::cancelTaskChain(const std::string& chainId)
{
    auto* chain = findTaskChain(chainId);
    if (!chain) {
        return false;
    }

    // 清除AGV任务和调度器控制（参考 taskchain.cpp:157, 207-210）
    if (m_vehicleService && chain->agvNumber >= 0) {
        auto* agv = m_vehicleService->getVehicle(chain->agvNumber);
        if (agv) {
            agv->setControlledByDispatcher(false);
        }

        // 清除AGV任务
        m_vehicleService->clearVehicleTask(chain->agvNumber);
    }

    finishTaskChain(*chain, false);

    if (m_logger) {
        m_logger->info(QString("Task chain %1 cancelled")
            .arg(QString::fromStdString(chainId)));
    }

    return true;
}

bool TaskExecutor::insertTaskBeforeCurrent(
    const std::string& chainId,
    std::unique_ptr<SubTaskBase> task)
{
    // 参考 taskchain.cpp:309-345

    auto* chain = findTaskChain(chainId);
    if (!chain || !task) {
        return false;
    }

    if (chain->currentTaskIndex >= chain->tasks.size()) {
        // 任务已完成，无法插入
        return false;
    }

    // 在当前任务索引位置插入
    chain->tasks.insert(
        chain->tasks.begin() + chain->currentTaskIndex,
        std::move(task)
    );

    if (m_logger) {
        m_logger->info(QString("Task inserted before current in chain %1 at index %2")
            .arg(QString::fromStdString(chainId))
            .arg(chain->currentTaskIndex));
    }

    return true;
}

bool TaskExecutor::insertTaskAfterCurrent(
    const std::string& chainId,
    std::unique_ptr<SubTaskBase> task)
{
    auto* chain = findTaskChain(chainId);
    if (!chain || !task) {
        return false;
    }

    if (chain->currentTaskIndex >= chain->tasks.size()) {
        // 任务已完成，追加到末尾
        chain->tasks.push_back(std::move(task));
    } else {
        // 在当前任务后插入
        chain->tasks.insert(
            chain->tasks.begin() + chain->currentTaskIndex + 1,
            std::move(task)
        );
    }

    if (m_logger) {
        m_logger->debug(QString("Task inserted after current in chain %1")
            .arg(QString::fromStdString(chainId)));
    }

    return true;
}

bool TaskExecutor::setChainStatus(
    const std::string& chainId,
    kernel::task::TaskChainStatus status)
{
    auto* chain = findTaskChain(chainId);
    if (!chain) {
        return false;
    }

    chain->status = status;

    if (m_logger) {
        m_logger->debug(QString("Chain %1 status set to %2")
            .arg(QString::fromStdString(chainId))
            .arg(QString::fromStdString(
                kernel::task::taskChainStatusToString(status))));
    }

    return true;
}

const TaskChainState* TaskExecutor::getTaskChainState(const std::string& chainId) const
{
    auto it = std::find_if(m_activeChains.begin(), m_activeChains.end(),
        [&chainId](const TaskChainState& chain) {
            return chain.chainId == chainId;
        });

    if (it != m_activeChains.end()) {
        return &(*it);
    }

    return nullptr;
}

std::vector<std::string> TaskExecutor::getActiveChainIds() const
{
    std::vector<std::string> chainIds;
    chainIds.reserve(m_activeChains.size());

    for (const auto& chain : m_activeChains) {
        if (!chain.finished) {
            chainIds.push_back(chain.chainId);
        }
    }

    return chainIds;
}

std::vector<std::string> TaskExecutor::getChainIdsByAgv(int agvNumber) const
{
    std::vector<std::string> chainIds;

    for (const auto& chain : m_activeChains) {
        if (chain.agvNumber == agvNumber && !chain.finished) {
            chainIds.push_back(chain.chainId);
        }
    }

    return chainIds;
}

bool TaskExecutor::hasActiveChainForAgv(int agvNumber) const
{
    if (agvNumber < 0) {
        return false;
    }
    return std::any_of(m_activeChains.begin(), m_activeChains.end(),
        [agvNumber](const TaskChainState& chain) {
            return !chain.finished && chain.agvNumber == agvNumber;
        });
}

bool TaskExecutor::hasActiveTaskByName(const std::string& taskName) const
{
    if (taskName.empty()) {
        return false;
    }
    return std::any_of(m_activeChains.begin(), m_activeChains.end(),
        [&taskName](const TaskChainState& chain) {
            return !chain.finished && chain.taskName == taskName;
        });
}

void TaskExecutor::start()
{
    m_executionTimer.start(m_executionInterval);

    if (m_logger) {
        m_logger->info("TaskExecutor started");
    }
}

void TaskExecutor::stop()
{
    m_executionTimer.stop();

    if (m_logger) {
        m_logger->info("TaskExecutor stopped");
    }
}

bool TaskExecutor::resetCurrentSubTask(const std::string& chainId)
{
    auto* chain = findTaskChain(chainId);
    if (!chain) {
        return false;
    }

    if (chain->tasks.empty() || chain->currentTaskIndex >= chain->tasks.size()) {
        return false;
    }

    auto* currentTask = chain->tasks[chain->currentTaskIndex].get();
    if (!currentTask) {
        return false;
    }

    currentTask->reset();
    chain->status = kernel::task::TaskChainStatus::Ok;
    chain->paused = false;
    chain->context.clearError();

    if (m_logger) {
        m_logger->info(QString("Reset current subtask for chain %1 (index %2)")
                           .arg(QString::fromStdString(chain->chainId))
                           .arg(static_cast<int>(chain->currentTaskIndex)));
    }

    return true;
}

void TaskExecutor::setExecutionInterval(int intervalMs)
{
    m_executionInterval = intervalMs;

    if (m_executionTimer.isActive()) {
        m_executionTimer.setInterval(intervalMs);
    }
}

void TaskExecutor::executeStep()
{
    // 执行所有活跃的任务链
    for (auto& chain : m_activeChains) {
        if (!chain.finished && !chain.paused) {
            executeSingleChain(chain);
        }
    }

    // 清理已完成的任务链
    removeFinishedChains();
}

std::string TaskExecutor::generateChainId()
{
    uint64_t counter = s_chainCounter.fetch_add(1);
    auto now = std::chrono::system_clock::now();
    auto timestamp = std::chrono::system_clock::to_time_t(now);

    std::ostringstream oss;
    oss << "CHAIN_" << timestamp << "_" << std::setfill('0') << std::setw(6) << counter;
    return oss.str();
}

TaskChainState* TaskExecutor::findTaskChain(const std::string& chainId)
{
    auto it = std::find_if(m_activeChains.begin(), m_activeChains.end(),
        [&chainId](const TaskChainState& chain) {
            return chain.chainId == chainId;
        });

    if (it != m_activeChains.end()) {
        return &(*it);
    }

    return nullptr;
}

void TaskExecutor::executeSingleChain(TaskChainState& chain)
{
    // 参考 taskchain.cpp:198-390 的完整状态处理逻辑

    if (!chain.context.agv && m_vehicleService && chain.agvNumber >= 0) {
        chain.context.agv = m_vehicleService->getVehicle(chain.agvNumber);
    }

    if (chain.context.agv) {
        chain.context.currentMap = chain.context.agv->getCurrentMap();
    }

    applyContextUpdates(chain);

    // 检查是否所有任务都已完成
    if (chain.currentTaskIndex >= chain.tasks.size()) {
        finishTaskChain(chain, true);
        return;
    }

    // 获取当前任务
    auto& currentTask = chain.tasks[chain.currentTaskIndex];

    // ==================== 状态处理（参考三方） ====================

    // 处理挂起状态
    if (chain.status == kernel::task::TaskChainStatus::Suspend) {
        emit taskChainStatusUpdated(
            QString::fromStdString(chain.chainId),
            "Suspended"
        );

        if (chain.suspendCount > 0) {
            chain.suspendCount--;
        } else {
            // 挂起计数结束，恢复正常
            chain.status = kernel::task::TaskChainStatus::Ok;
        }
        return;  // 挂起时不执行任务
    }

    // 处理任务保持状态
    if (chain.status == kernel::task::TaskChainStatus::KeepOn) {
        emit taskChainStatusUpdated(
            QString::fromStdString(chain.chainId),
            "KeepOn"
        );
        return;  // 保持时不执行任务
    }

    // 处理错误状态
    if (chain.status == kernel::task::TaskChainStatus::Error) {
        if (m_logger) {
            m_logger->error(QString("Task chain %1 in error state: %2")
                .arg(QString::fromStdString(chain.chainId))
                .arg(QString::fromStdString(chain.context.errorMessage)));
        }

        emit taskChainStatusUpdated(
            QString::fromStdString(chain.chainId),
            "Error"
        );

        finishTaskChain(chain, false);
        return;
    }

    // 处理路径重计算状态（参考 taskchain.cpp:297-346）
    if (chain.status == kernel::task::TaskChainStatus::Recalculation) {
        handleRecalculation(chain, currentTask.get());
        return;
    }

    // 处理移动到管控区外状态（参考 taskchain.cpp:348-364）
    if (chain.status == kernel::task::TaskChainStatus::DispatcherMove) {
        handleDispatcherMove(chain);
        return;
    }

    // ==================== 正常执行任务 ====================

    if (chain.status == kernel::task::TaskChainStatus::Ok ||
        chain.status == kernel::task::TaskChainStatus::Timeout) {
        // 执行当前任务
        auto stage = currentTask->execute(chain.context);
        applyContextUpdates(chain);

        if (chain.status != kernel::task::TaskChainStatus::Ok &&
            chain.status != kernel::task::TaskChainStatus::Timeout) {
            return;
        }

        emit taskChainStatusUpdated(
            QString::fromStdString(chain.chainId),
            chain.status == kernel::task::TaskChainStatus::Timeout ? "Timeout" : "Running"
        );

        // 如果任务完成，移动到下一个任务
        if (stage == kernel::task::TaskStage::Finished) {
            chain.currentTaskIndex++;

            // 发出进度更新信号
            emit taskChainProgressUpdated(
                QString::fromStdString(chain.chainId),
                static_cast<int>(chain.currentTaskIndex),
                static_cast<int>(chain.tasks.size())
            );

            // 检查是否有错误
            if (chain.context.hasError()) {
                chain.status = kernel::task::TaskChainStatus::Error;
                return;
            }

            // 如果是最后一个任务，完成任务链
            if (chain.currentTaskIndex >= chain.tasks.size()) {
                finishTaskChain(chain, true);
            }
        }
    }
}

void TaskExecutor::handleRecalculation(TaskChainState& chain, SubTaskBase* currentTask)
{
    emit taskChainStatusUpdated(
        QString::fromStdString(chain.chainId),
        "Recalculation"
    );

    if (!currentTask) {
        if (m_logger) {
            m_logger->error(QString("Task chain %1 requested recalculation but current task is null")
                .arg(QString::fromStdString(chain.chainId)));
        }
        chain.status = kernel::task::TaskChainStatus::Error;
        chain.context.setError("Recalculation requested but no active task");
        return;
    }

    if (m_logger) {
        m_logger->info(QString("Task chain %1 performing recalculation for task type %2")
            .arg(QString::fromStdString(chain.chainId))
            .arg(QString::fromStdString(kernel::task::taskTypeToString(currentTask->getType()))));
    }

    auto insertMoveTask = [&](const std::string& station, int floor) -> bool {
        if (!m_vehicleService || !m_dispatcherService) {
            if (m_logger) {
                m_logger->warning(QString("Cannot insert move task during recalculation for chain %1 due to missing services")
                    .arg(QString::fromStdString(chain.chainId)));
            }
            return false;
        }

        try {
            auto moveTask = std::make_unique<MoveTask>(
                station,
                floor,
                m_vehicleService,
                m_dispatcherService,
                m_mapService,
                m_logger
            );

            chain.tasks.insert(
                chain.tasks.begin() + static_cast<std::ptrdiff_t>(chain.currentTaskIndex),
                std::move(moveTask)
            );
            return true;
        } catch (const std::exception& ex) {
            if (m_logger) {
                m_logger->error(QString("Failed to insert move task during recalculation for chain %1: %2")
                    .arg(QString::fromStdString(chain.chainId))
                    .arg(QString::fromUtf8(ex.what())));
            }
            return false;
        }
    };

    bool handled = false;
    const auto taskType = currentTask->getType();

    switch (taskType) {
    case kernel::task::TaskType::Move: {
        auto moveTask = dynamic_cast<MoveTask*>(currentTask);
        if (!moveTask) {
            break;
        }

        int currentFloor = resolveAgvFloor(chain);
        int targetFloor = moveTask->getFloor();
        if (currentFloor < 0 || targetFloor <= 0 || currentFloor == targetFloor) {
            break;
        }

        if (!m_mapService) {
            if (m_logger) {
                m_logger->error(QString("Cross-floor recalculation failed for chain %1: map service unavailable")
                    .arg(QString::fromStdString(chain.chainId)));
            }
            chain.status = kernel::task::TaskChainStatus::Error;
            chain.context.setError("Map service unavailable for cross-floor recalculation");
            return;
        }

        auto liftManager = m_mapService->getLiftManager();
        if (!liftManager) {
            if (m_logger) {
                m_logger->error(QString("Cross-floor recalculation failed for chain %1: lift manager unavailable")
                    .arg(QString::fromStdString(chain.chainId)));
            }
            chain.status = kernel::task::TaskChainStatus::Error;
            chain.context.setError("Lift manager unavailable for cross-floor recalculation");
            return;
        }

        auto liftPath = liftManager->findLiftPath(currentFloor, targetFloor);
        if (liftPath.isEmpty()) {
            if (m_logger) {
                m_logger->error(QString("Cross-floor recalculation failed for chain %1: no lift path from %2F to %3F")
                    .arg(QString::fromStdString(chain.chainId))
                    .arg(currentFloor)
                    .arg(targetFloor));
            }
            chain.status = kernel::task::TaskChainStatus::Error;
            chain.context.setError("No available lift path for cross-floor movement");
            return;
        }

        std::vector<std::unique_ptr<SubTaskBase>> newTasks;
        newTasks.reserve(static_cast<std::size_t>(liftPath.size()) * 4);
        std::unordered_set<std::string> uniqueStations;

        auto appendMoveTask = [&](const QString& station, int floor) {
            if (station.isEmpty() || floor <= 0) {
                return;
            }
            std::string stationId = station.toStdString();
            if (stationId.empty() || !uniqueStations.insert(stationId).second) {
                return;
            }
            newTasks.push_back(std::make_unique<MoveTask>(
                stationId,
                floor,
                m_vehicleService,
                m_dispatcherService,
                m_mapService,
                m_logger));
        };

        for (const auto& segment : liftPath) {
            const int segmentStartFloor = segment.startFloor.floor > 0 ? segment.startFloor.floor : currentFloor;
            const int segmentTargetFloor = segment.targetFloor.floor > 0 ? segment.targetFloor.floor : targetFloor;

            appendMoveTask(segment.startFloor.askPoint, segmentStartFloor);

            newTasks.push_back(std::make_unique<LiftTask>(
                m_vehicleService,
                m_mapService,
                m_dispatcherService,
                m_logger,
                segment.liftNum,
                segmentStartFloor,
                segmentTargetFloor));

            if (m_logger) {
                m_logger->info(QString("Prepared lift segment via lift %1: %2F -> %3F")
                                   .arg(segment.liftNum)
                                   .arg(segmentStartFloor)
                                   .arg(segmentTargetFloor));
            }
        }

        if (newTasks.empty()) {
            if (m_logger) {
                m_logger->error(QString("Cross-floor recalculation failed for chain %1: unable to prepare subtasks")
                    .arg(QString::fromStdString(chain.chainId)));
            }
            chain.status = kernel::task::TaskChainStatus::Error;
            chain.context.setError("Failed to compose cross-floor subtasks");
            return;
        }

        chain.tasks.insert(
            chain.tasks.begin() + static_cast<std::ptrdiff_t>(chain.currentTaskIndex),
            std::make_move_iterator(newTasks.begin()),
            std::make_move_iterator(newTasks.end()));

        handled = true;

        if (m_logger) {
            m_logger->info(QString("Inserted cross-floor sequence with %1 lift segment(s) for chain %2 (%3F -> %4F)")
                .arg(static_cast<int>(liftPath.size()))
                .arg(QString::fromStdString(chain.chainId))
                .arg(currentFloor)
                .arg(targetFloor));
        }
        break;
    }
    case kernel::task::TaskType::Charge: {
        std::string stationId;
        int targetFloor = -1;
        if (auto chargeTask = dynamic_cast<ChargeTask*>(currentTask)) {
            stationId = chargeTask->getNavigationTarget();
            targetFloor = chargeTask->getNavigationFloor();
        }
        if (stationId.empty()) {
            if (auto charge = chain.context.chargePoint.lock()) {
                stationId = charge->getStationPoint().toStdString();
                targetFloor = charge->getFloor();
            }
        }
        if (stationId.empty()) {
            break;
        }
        if (targetFloor <= 0) {
            targetFloor = resolveAgvFloor(chain);
        }
        handled = insertMoveTask(stationId, targetFloor);
        break;
    }
    case kernel::task::TaskType::Park:
        if (auto park = chain.context.parkPoint.lock()) {
            auto stationId = park->getStationName().toStdString();
            if (stationId.empty()) {
                if (m_logger) {
                    m_logger->error(QString("Park point %1 lacks station mapping, cannot request navigation")
                        .arg(park->getPointId()));
                }
                break;
            }
            handled = insertMoveTask(stationId, park->getFloor());
        }
        break;
    case kernel::task::TaskType::Lift: {
        auto liftTask = dynamic_cast<LiftTask*>(currentTask);
        if (!liftTask) {
            break;
        }

        const auto stationId = liftTask->getCallAskPointStation();
        const int callFloor = liftTask->getCallFloor();
        if (stationId.empty() || callFloor <= 0) {
            if (m_logger) {
                m_logger->warning(QString("Lift task recalculation lacks valid ask point (chain %1)")
                    .arg(QString::fromStdString(chain.chainId)));
            }
            break;
        }

        handled = insertMoveTask(stationId, callFloor);
        if (m_logger && handled) {
            m_logger->info(QString("Inserted move-to-lift task for chain %1 (station %2, floor %3)")
                .arg(QString::fromStdString(chain.chainId))
                .arg(QString::fromStdString(stationId))
                .arg(callFloor));
        }
        break;
    }
    default:
        break;
    }

    currentTask->reset();

    if (!handled && !chain.midMoveStation.empty()) {
        chain.status = kernel::task::TaskChainStatus::DispatcherMove;
        return;
    }

    chain.status = kernel::task::TaskChainStatus::Ok;
}

void TaskExecutor::handleDispatcherMove(TaskChainState& chain)
{
    emit taskChainStatusUpdated(
        QString::fromStdString(chain.chainId),
        "DispatcherMove"
    );

    if (chain.midMoveStation.empty()) {
        chain.status = kernel::task::TaskChainStatus::Ok;
        return;
    }

    if (!m_dispatcherService || !m_vehicleService) {
        if (m_logger) {
            m_logger->warning(QString("Dispatcher move requested for chain %1 but services are unavailable")
                .arg(QString::fromStdString(chain.chainId)));
        }
        chain.midMoveStation.clear();
        chain.status = kernel::task::TaskChainStatus::Ok;
        return;
    }

    if (chain.currentTaskIndex > chain.tasks.size()) {
        chain.currentTaskIndex = chain.tasks.size();
    }

    int targetFloor = resolveAgvFloor(chain);
    if (targetFloor < 0) {
        targetFloor = 1;
    }

    try {
        auto moveTask = std::make_unique<MoveTask>(
            chain.midMoveStation,
            targetFloor,
            m_vehicleService,
            m_dispatcherService,
            m_mapService,
            m_logger
        );

        chain.tasks.insert(
            chain.tasks.begin() + static_cast<std::ptrdiff_t>(chain.currentTaskIndex),
            std::move(moveTask)
        );

        if (m_logger) {
            m_logger->info(QString("Inserted dispatcher move task to %1 for chain %2")
                .arg(QString::fromStdString(chain.midMoveStation))
                .arg(QString::fromStdString(chain.chainId)));
        }
    } catch (const std::exception& ex) {
        if (m_logger) {
            m_logger->error(QString("Failed to insert dispatcher move task for chain %1: %2")
                .arg(QString::fromStdString(chain.chainId))
                .arg(QString::fromUtf8(ex.what())));
        }
        chain.status = kernel::task::TaskChainStatus::Error;
        chain.context.setError("Failed to insert dispatcher move task");
        return;
    }

    chain.midMoveStation.clear();
    chain.status = kernel::task::TaskChainStatus::Ok;
}

void TaskExecutor::handleDispatchEvent(int agvNumber,
                                       const QList<QString>& segment)
{
    for (auto& chain : m_activeChains) {
        if (chain.agvNumber != agvNumber) {
            continue;
        }
        if (chain.finished) {
            continue;
        }
        if (chain.currentTaskIndex >= chain.tasks.size()) {
            continue;
        }

        auto* currentTask = chain.tasks[chain.currentTaskIndex].get();
        if (auto moveTask = dynamic_cast<MoveTask*>(currentTask)) {
            moveTask->notifyDispatch(segment);
            if (m_logger) {
                QString info =
                    segment.isEmpty() ? QStringLiteral("<empty>")
                                      : QString("%1 -> %2").arg(segment.first()).arg(segment.last());
                m_logger->debug(QString("Dispatch event received for AGV %1: %2")
                                    .arg(agvNumber)
                                    .arg(info));
            }
            break;
        }
    }
}

void TaskExecutor::finishTaskChain(TaskChainState& chain, bool success)
{
    chain.finished = true;

    if (chain.currentTaskIndex < chain.tasks.size()) {
        if (auto* currentTask = chain.tasks[chain.currentTaskIndex].get()) {
            currentTask->forceCleanup(chain.context);
        }
    }

    releaseResources(chain);

    // 释放AGV调度器控制（参考 taskchain.cpp:270）
    if (m_vehicleService && chain.agvNumber >= 0) {
        if (auto* agv = m_vehicleService->getVehicle(chain.agvNumber)) {
            agv->setControlledByDispatcher(false);
            agv->setBusyStatus(false);
        }
    }
    if (m_dispatcherService && chain.agvNumber >= 0) {
        m_dispatcherService->cancelPendingForAgv(chain.agvNumber);
    }

    // TODO: 释放资源（电梯、充电桩、泊车位、占用区域）
    // 参考 taskchain.cpp:259-269
    // if (chain.liftPtr) { /* release lift */ }
    // if (chain.chargePtr) { /* release charge */ }
    // if (chain.parkPtr) { /* release park */ }
    // for (auto* area : chain.occupiedAreas) { /* release area */ }

    if (m_logger) {
        if (success) {
            m_logger->info(QString("Task chain %1 completed successfully")
                .arg(QString::fromStdString(chain.chainId)));
        } else {
            m_logger->warning(QString("Task chain %1 failed or was cancelled")
                .arg(QString::fromStdString(chain.chainId)));
        }
    }

    // 发出完成信号
    emit taskChainCompleted(QString::fromStdString(chain.chainId), success);
}

void TaskExecutor::removeFinishedChains()
{
    // 移除已完成的任务链（延迟一段时间后移除，以便查询状态）
    auto now = std::chrono::system_clock::now();

    // 收集需要移除的任务链ID
    std::vector<QString> chainsToRemove;

    for (const auto& chain : m_activeChains) {
        if (chain.finished) {
            // 完成后保留10秒
            auto elapsed = std::chrono::duration_cast<std::chrono::seconds>(
                now - chain.createTime
            ).count();

            if (elapsed > 10) {
                chainsToRemove.push_back(QString::fromStdString(chain.chainId));
            }
        }
    }

    // 发射移除信号并从列表中移除
    for (const auto& chainId : chainsToRemove) {
        m_activeChains.erase(
            std::remove_if(m_activeChains.begin(), m_activeChains.end(),
                [&chainId](const TaskChainState& chain) {
                    return QString::fromStdString(chain.chainId) == chainId;
                }),
            m_activeChains.end()
        );

        // 发射任务链移除信号,让ViewModel可以即时清理缓存
        emit taskChainRemoved(chainId);
    }
}

void TaskExecutor::applyContextUpdates(TaskChainState& chain)
{
    auto& ctx = chain.context;

    if (ctx.statusRequest.has_value()) {
        auto requested = ctx.statusRequest.value();
        chain.status = requested;

        if (requested == kernel::task::TaskChainStatus::Suspend) {
            if (ctx.suspendCountRequest > 0) {
                chain.suspendCount = ctx.suspendCountRequest;
            }
        } else if (requested == kernel::task::TaskChainStatus::DispatcherMove) {
            if (ctx.dispatcherMoveRequested) {
                chain.midMoveStation = ctx.dispatcherMidMoveStation;
            }
        } else if (requested == kernel::task::TaskChainStatus::Ok) {
            chain.suspendCount = 0;
            chain.midMoveStation.clear();
        }

        ctx.clearStatusRequest();
    }

    chain.occupiedAreas = ctx.occupiedAreas;
    chain.chargePtr = ctx.chargePoint;
    chain.parkPtr = ctx.parkPoint;
    chain.liftPtr = ctx.liftHandle;
}

int TaskExecutor::resolveAgvFloor(const TaskChainState& chain) const
{
    if (!m_mapService) {
        return -1;
    }

    if (chain.context.agv) {
        const auto& mapName = chain.context.agv->getCurrentMap();
        if (!mapName.empty()) {
            int floor = m_mapService->getFloorForMapName(QString::fromStdString(mapName));
            if (floor != -1) {
                return floor;
            }
        }
    }

    return m_mapService->getCurrentFloor();
}

void TaskExecutor::releaseResources(TaskChainState& chain)
{
    // 释放占用区域
    std::vector<std::weak_ptr<area::Area>> areaRefs = chain.occupiedAreas;
    for (const auto& areaWeak : chain.context.occupiedAreas) {
        bool exists = false;
        if (auto areaPtr = areaWeak.lock()) {
            for (const auto& existingWeak : areaRefs) {
                if (auto existing = existingWeak.lock()) {
                    if (existing.get() == areaPtr.get()) {
                        exists = true;
                        break;
                    }
                }
            }
            if (!exists) {
                areaRefs.emplace_back(areaWeak);
            }
        }
    }

    for (auto& areaWeak : areaRefs) {
        if (auto area = areaWeak.lock()) {
            if (chain.agvNumber >= 0) {
                area->releaseOccupation(chain.agvNumber);
            }
        }
    }
    chain.occupiedAreas.clear();
    chain.context.clearOccupiedAreas();

    // 释放电梯
    std::weak_ptr<lift::BaseLift> liftRef = chain.liftPtr;
    if (liftRef.expired()) {
        liftRef = chain.context.liftHandle;
    }
    if (auto lift = liftRef.lock()) {
        bool released = lift->release();
        if (!released && m_logger) {
            m_logger->warning(QString("Failed to release lift for chain %1")
                .arg(QString::fromStdString(chain.chainId)));
        }
    }
    chain.liftPtr.reset();
    chain.context.clearLiftHandle();

    // 释放充电桩
    std::weak_ptr<charge::ChargePoint> chargeRef = chain.chargePtr;
    if (chargeRef.expired()) {
        chargeRef = chain.context.chargePoint;
    }
    if (auto charge = chargeRef.lock()) {
        if (chain.agvNumber >= 0) {
            charge->releasePreOccupation(chain.agvNumber);
        }
    }
    chain.chargePtr.reset();
    chain.context.clearChargePoint();

    // 释放泊车位
    std::weak_ptr<park::ParkPoint> parkRef = chain.parkPtr;
    if (parkRef.expired()) {
        parkRef = chain.context.parkPoint;
    }
    if (auto park = parkRef.lock()) {
        if (chain.agvNumber >= 0) {
            park->releasePreOccupation(chain.agvNumber);
        }
    }
    chain.parkPtr.reset();
    chain.context.clearParkPoint();
}

} // namespace task
} // namespace application
